quiz menu system


代写完成–Java命令行菜单程序:考试系统


Background

As described in the handout for Part 1, the overall aim of the assignment is to develop a menu-driven program to administer a quiz test.

In Part 1, you have implemented the classes to represent the quiz questions and answers. You have also written programs to test these classes. In particular, you have written a program to read a number of questions from a text file, administer the questions, obtain the answers, and print out the answers.

Building on the work that you have done for Part 1, in this Part 2, you are required to do the tasks described below.

Besides the information given in the tasks below, please refer to Part 1 of the Assignment for any other information you may need.

Task 1

Modify the classes QuizQuestion and QuizAnswer and their subclasses to use ArrayList instead of array whenever you need to maintain a collection.

Test your classes with the provided BasicTester program.

Task 2

(For Tasks 2, 3 and 4, you must also use ArrayList whenever you need to maintain collections.)
This task does not required you to do any exception handling. (That will done in Tasks 3 and 4).
Write a menu program called QuizMenu. The program displays the menu with the options shown below:

1
2
3
4
5
6
7
8
9
10
11
======== 
Options:
========
R: Read question details from a text file
A: Administer the quiz test
F: Administer the quiz test with option to quit
D: Display the answers on the screen
W: Write the answers to a text file
Q: Quit

Please select an option:

Other than the minimum required for the program to compile, no exception handling is required for this task.

Option R. The program asks for the name of the text file (e.g. qq.txt) and reads the questions from this file. The file name (to be entered) includes the file extension. The file format is exactly as described in Part 1.

Option A. The way the program administers the quiz questions and obtains the answers is exactly as described in Part 1.

Option F. (‘F’ stands for ‘Flexible administration of the quiz test’). With this option, after answering a quiz question, the user will be asked if he/she wants to continue or not. If the user chooses to quit early, options D and W are still available to display and save the results of the questions have been answered. The behavior of the program is illustrated with a sample run below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
======== 
Options:
========
R: Read question details from a text file
A: Administer the quiz test
F: Administer the quiz test with option to quit
D: Display the answers on the screen W: Write the answers to a text file
Q: Quit

Please select an option: f

Question 1
A try statement must have a catch block. True or false?
Type true or false in lower case: true

Do you want to continue? (y/n): y
Question 2
FileNotFoundException is a/an _____ exception. Fill in the blank Type in your answer: checked Do you want to continue? (y/n): n

========
Options:
========
R: Read question details from a text file
A: Administer the quiz test
F: Administer the quiz test with option to quit
D: Display the answers on the screen W: Write the answers to a text file
Q: Quit

Please select an option:

Option D. The way the program displays the answer is illustrated by the example below:

1
2
3
4
5
6
7
8
9
Question 1
TrueFalseAnswer[quizQuestion: TrueFalseQuestion[question: A try statement must have a catch block., correctAnswer: false] , userAnswer: true, result: I]

Question 2
WordAnswer[quizQuestion: WordQuestion[question: FileNotFoundException is a/an _____ exception. Fill in the blank., correctAnswer: checked, caseSensitive: false] , userAnswer: checked, result: C]

Number of questions: 5 Number of answers: 2
Number of correct answers: 1
Number of incorrect answers: 1

As illustrated above, the display of the result of a quiz test ends with four lines of summary.

Option W. The program asks for the name of the file to save the result to (e.g. result.txt). The information to be written and the format are exactly as for displaying the result on the screen.

Hints:

  • For each menu option (except “quit”), you should have a method to carry out the required operation.

  • Test your program with both qq.txt and qqe.txt (which has a format error).

Task 3

The menu-driven program of Task 2 can crash. For Task 3, you are required to enhance the program of Task 2 to prevent it from crashing.

More specifically, we want to achieve the following objective:

When the program carries out the operation required for a menu option, if some exceptional condition arises, the program will display a message to inform the user of the occurrence of the exception, terminate the operation and return to the main menu.

In this way, the program does not crash, and all the work up to that point (before the failed operation) is preserved and further operations can be taken.

Make a copy of the previous menu program and call it QuizMenuRobust.java. Modify it to make it robust as described above.

Task 4

We now seek to enhance the program of Task 3 to remove some of its shortcomings.

Examples of shortcomings of program QuizMenuRobust

It does not make sense to administer a quiz when it has not been read. So ideally, if the user tries to administer a quiz before it is read, the program should display an error message, and terminate the operation and return to the main menu.

This is not the behavior of program of Task 3. How it behaves depend on whether the list of question instances has been initialized to an empty list or not.

  • If the list of answer objects has not been initialized, i.e. it is a null object, a message about null pointer exception is displayed before returning to the main menu.

  • If the list has been initialized to an empty ArrayList, the program returns immediately to the main menu because an empty list of questions has been administered.

As another example, if you read the file qqe.txt, an exception occurs, and the program returns to the main menu. But a number of questions has been read, and the list has a number of question instances. You can see this by choosing option A next.

This behavior is generally not regarded as being satisfactory. Normally, if an operation like this fails, we would like to restore things to their states prior to the failed operation. (This is what rollback operation in database is about.)

The state of the menu-driven program

As mentioned before, if the user tries to administer a quiz before it is read, the program should display an error message, and terminate the operation and return to the main menu.

In order to make that sort of behavior possible, one solution is to regard the program as what is known as a state machine. By that, we mean we regard the program an entity that can go through a number of states and the state that it is in can affect its behavior.

As a solution adequate for our purpose, we can regard the program as an entity that can be in one of three states represented by the three constants declared below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

private static final int QUIZ_NOT_READ = 1;

// A quiz has not been read or has not been read successfully.

// When the program is in this state, there is not available

// a list of quiz objects to be administered.

private static final int QUIZ_AVAILABLE = 2;

// A quiz has been read and is available but it has not been

// administered. When the program is in this state, there is not

// a list of answer objects to be displayed or saved.

private static final int QUIZ_TAKEN = 3;

// A quiz has been administered, and the answers are available

// for displaying or saving to file

// More information related to these states is given below

Then we should have a variable – let us call it state – to keep track of the state that the program is in.

Initially, the state should be QUIZ_NOT_READ. When a quiz is successfully read in, the state should be QUIZ_AVAILABLE. When a quiz is successfully administered, completely or with early exit, the state should be QUIZ_TAKEN.

Enhancement features

Make a copy of QuizMenuRobust, change the name to QuizMenuEnhanced, and modify it to implement the enhancement features described below:

For option R (read questions)

E1 If the operation completes successfully, the state must be set to QUIZ_AVAILABLE E2 If the operation fails (and throws an exception),

  • The list of question objects must be set to null

  • The state must be set to QUIZ_NOT_READ

E3 If the user chooses option R when the state is QUIZ_AVAILABLE or QUIZ_TAKEN,

  • Ask the user if they really want to read a new quiz, and then proceed accordingly.

  • If the user confirms that they want to proceed with reading in a new quiz, then we prepare a “clean sheet” first with the following actions

    • Set the state to QUIZ_NOT_READ
    • Set the lists of question and answer objects to null before proceed to reading the questions.

NOTE: If the subsequent reading is completed successfully, the state must be set to QUIZ_AVAILABE. If the subsequent reading fails, the state must be QUIZ_NOT_READ. See E1 and E2 above.

For options A and F (administer the quiz)

E4 If the operation completes successfully, the state must be set to QUIZ_TAKEN.
E5 If the operation fails,

  • The list of answer objects must be set to null

  • the state must be QUIZ_AVAILABE

E6 If the user tries option A or F when the state is QUIZ_NOT_READ, display an error message, terminate the operation and return to the main menu.

E7 If the user tries to administer a quiz when the state is QUIZ_TAKEN,

  • Ask the user if they really want to take the test again, and then proceed accordingly.

  • If the user confirms that they want to proceed with this option, then

    • The list of answer instances must be set to null
    • The state must be set to QUIZ_AVAILABLE

NOTE: If the subsequent administering operation is completed successfully, the state must be set to QUIZ_TAKEN. If the operation fails, the state must be QUIZ_AVAILABLE. See E4 and E5.

For options D and W (display and save answers)

E8 If the user tries option D or W when the state is not QUIZ_TAKEN, display an error message, terminate the operation and return to the main menu.